namespace KeyShow
{
    using System;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.Drawing;
    using System.Collections.Generic;
    using System.Text;

    public class MainForm : Form
    {
        private Label keyLabel;
        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
        private LowLevelKeyboardProc _keyboardProc;
        private LowLevelMouseProc _mouseProc;
        private IntPtr _keyboardHookID = IntPtr.Zero;
        private IntPtr _mouseHookID = IntPtr.Zero;
        private HashSet<Keys> _pressedKeys = new HashSet<Keys>();
        private string _lastKeyText = "";
        private ContextMenuStrip _contextMenu;
        private bool _isDragging = false;
        private Point _dragStartPoint;
        private ToolTip _toolTip;

        // 初始样式设置
        private static readonly Color InitialBackColor = Color.FromArgb(48, 25, 52); // 黑紫色
        private static readonly Color InitialForeColor = Color.White;
        private const double InitialOpacity = 0.8; // 80%透明度

        // 键盘钩子常量
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;
        private const int WM_KEYUP = 0x0101;
        private const int WM_SYSKEYDOWN = 0x0104;
        private const int WM_SYSKEYUP = 0x0105;

        // 鼠标钩子常量
        private const int WH_MOUSE_LL = 14;
        private const int WM_LBUTTONDOWN = 0x0201;
        private const int WM_LBUTTONUP = 0x0202;
        private const int WM_RBUTTONDOWN = 0x0204;
        private const int WM_RBUTTONUP = 0x0205;
        private const int WM_MBUTTONDOWN = 0x0207;
        private const int WM_MBUTTONUP = 0x0208;

        [StructLayout(LayoutKind.Sequential)]
        private struct POINT
        {
            public int x;
            public int y;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public uint mouseData;
            public uint flags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        public MainForm()
        {
            InitializeComponents();
            _keyboardProc = KeyboardHookCallback;
            _mouseProc = MouseHookCallback;
            _keyboardHookID = SetKeyboardHook(_keyboardProc);
            _mouseHookID = SetMouseHook(_mouseProc);
        }

        private void InitializeComponents()
        {
            this.Width = 300;
            this.Height = 150;
            this.FormBorderStyle = FormBorderStyle.None;
            this.MaximizeBox = false;
            this.TopMost = true;
            this.ShowInTaskbar = false;
            this.Icon = SystemIcons.Shield;

            // 设置初始样式
            this.BackColor = InitialBackColor;
            this.Opacity = InitialOpacity;

            // 设置窗体可以通过代码移动
            this.SetStyle(ControlStyles.ResizeRedraw, true);

            // 添加ToolTip控件
            _toolTip = new ToolTip();
            _toolTip.AutoPopDelay = 5000;
            _toolTip.InitialDelay = 500;
            _toolTip.ReshowDelay = 500;
            _toolTip.ShowAlways = true;

            keyLabel = new Label
            {
                AutoSize = false,
                TextAlign = ContentAlignment.MiddleCenter,
                Dock = DockStyle.Fill,
                Font = new Font("Arial", 20, FontStyle.Bold),
                ForeColor = InitialForeColor,
                Text = "右键自定义"
            };

            // 设置ToolTip
            _toolTip.SetToolTip(this, "欢迎使用Venus的keyshow！如果您有好的想法欢迎发邮件到617808324@qq.com与我交流");
            _toolTip.SetToolTip(keyLabel, "欢迎使用Venus的keyshow！如果您有好的想法欢迎发邮件到617808324@qq.com与我交流");

            // 创建右键菜单
            _contextMenu = new ContextMenuStrip();
            _contextMenu.Items.Add("设置背景色", null, (s, e) => SetBackgroundColor());
            _contextMenu.Items.Add("设置文字颜色", null, (s, e) => SetForegroundColor());
            _contextMenu.Items.Add("设置透明度", null, (s, e) => SetOpacity());
            _contextMenu.Items.Add("设置窗口大小", null, (s, e) => SetWindowSize());
            _contextMenu.Items.Add("-"); // 添加分隔线
            _contextMenu.Items.Add("退出", null, (s, e) => Application.Exit());

            // 设置右键菜单
            this.ContextMenuStrip = _contextMenu;
            keyLabel.ContextMenuStrip = _contextMenu;

            // 添加鼠标事件处理
            this.MouseDown += MainForm_MouseDown;
            this.MouseMove += MainForm_MouseMove;
            this.MouseUp += MainForm_MouseUp;

            // 确保Label也能触发窗体的鼠标事件
            keyLabel.MouseDown += MainForm_MouseDown;
            keyLabel.MouseMove += MainForm_MouseMove;
            keyLabel.MouseUp += MainForm_MouseUp;

            this.Controls.Add(keyLabel);
        }

        private void MainForm_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _isDragging = true;
                _dragStartPoint = new Point(e.X, e.Y);
            }
        }

        private void MainForm_MouseMove(object sender, MouseEventArgs e)
        {
            if (_isDragging)
            {
                Point currentPoint = PointToScreen(new Point(e.X, e.Y));
                Location = new Point(
                    currentPoint.X - _dragStartPoint.X,
                    currentPoint.Y - _dragStartPoint.Y);
            }
        }

        private void MainForm_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _isDragging = false;
            }
        }

        private void SetBackgroundColor()
        {
            using (ColorDialog colorDialog = new ColorDialog())
            {
                colorDialog.Color = this.BackColor;
                if (colorDialog.ShowDialog(this) == DialogResult.OK)
                {
                    this.BackColor = colorDialog.Color;
                }
            }
        }

        private void SetForegroundColor()
        {
            using (ColorDialog colorDialog = new ColorDialog())
            {
                colorDialog.Color = keyLabel.ForeColor;
                if (colorDialog.ShowDialog(this) == DialogResult.OK)
                {
                    keyLabel.ForeColor = colorDialog.Color;
                }
            }
        }

        private void SetOpacity()
        {
            // 临时禁用主窗口的TopMost
            bool wasTopMost = this.TopMost;
            this.TopMost = false;

            using (Form opacityForm = new Form())
            {
                opacityForm.Width = 300;
                opacityForm.Height = 100;
                opacityForm.FormBorderStyle = FormBorderStyle.FixedDialog;
                opacityForm.Text = "设置透明度";
                opacityForm.StartPosition = FormStartPosition.Manual;
                opacityForm.MaximizeBox = false;
                opacityForm.MinimizeBox = false;
                opacityForm.ShowInTaskbar = false;
                opacityForm.Owner = this;
                opacityForm.TopMost = true;

                // 计算对话框位置，确保在屏幕内
                Point dialogLocation = new Point(
                    this.Location.X + (this.Width - opacityForm.Width) / 2,
                    this.Location.Y + this.Height + 10
                );

                // 确保对话框在屏幕范围内
                Screen screen = Screen.FromControl(this);
                if (dialogLocation.X + opacityForm.Width > screen.WorkingArea.Right)
                    dialogLocation.X = screen.WorkingArea.Right - opacityForm.Width;
                if (dialogLocation.Y + opacityForm.Height > screen.WorkingArea.Bottom)
                    dialogLocation.Y = this.Location.Y - opacityForm.Height - 10;

                opacityForm.Location = dialogLocation;

                TrackBar trackBar = new TrackBar
                {
                    Minimum = 20,
                    Maximum = 100,
                    Value = (int)(this.Opacity * 100),
                    TickFrequency = 10,
                    Width = 250,
                    Location = new Point(25, 20)
                };

                Label valueLabel = new Label
                {
                    AutoSize = true,
                    Location = new Point(130, 45),
                    Text = string.Format("{0}%", trackBar.Value)
                };

                trackBar.ValueChanged += (s, e) =>
                {
                    this.Opacity = trackBar.Value / 100.0;
                    valueLabel.Text = string.Format("{0}%", trackBar.Value);
                };

                opacityForm.Controls.Add(trackBar);
                opacityForm.Controls.Add(valueLabel);
                opacityForm.ShowDialog(this);
            }

            // 恢复主窗口的TopMost状态
            this.TopMost = wasTopMost;
        }

        private void SetWindowSize()
        {
            // 临时禁用主窗口的TopMost
            bool wasTopMost = this.TopMost;
            this.TopMost = false;

            using (Form sizeForm = new Form())
            {
                sizeForm.Width = 300;
                sizeForm.Height = 150;
                sizeForm.FormBorderStyle = FormBorderStyle.FixedDialog;
                sizeForm.Text = "设置窗口大小";
                sizeForm.StartPosition = FormStartPosition.Manual;
                sizeForm.MaximizeBox = false;
                sizeForm.MinimizeBox = false;
                sizeForm.ShowInTaskbar = false;
                sizeForm.Owner = this;
                sizeForm.TopMost = true;

                // 计算对话框位置
                Point dialogLocation = new Point(
                    this.Location.X + (this.Width - sizeForm.Width) / 2,
                    this.Location.Y + this.Height + 10
                );

                // 确保对话框在屏幕范围内
                Screen screen = Screen.FromControl(this);
                if (dialogLocation.X + sizeForm.Width > screen.WorkingArea.Right)
                    dialogLocation.X = screen.WorkingArea.Right - sizeForm.Width;
                if (dialogLocation.Y + sizeForm.Height > screen.WorkingArea.Bottom)
                    dialogLocation.Y = this.Location.Y - sizeForm.Height - 10;

                sizeForm.Location = dialogLocation;

                TableLayoutPanel panel = new TableLayoutPanel
                {
                    ColumnCount = 2,
                    RowCount = 3,
                    Dock = DockStyle.Fill,
                    Padding = new Padding(10)
                };

                Label widthLabel = new Label { Text = "宽度:", Anchor = AnchorStyles.Left };
                Label heightLabel = new Label { Text = "高度:", Anchor = AnchorStyles.Left };

                NumericUpDown widthUpDown = new NumericUpDown
                {
                    Minimum = 100,
                    Maximum = 1000,
                    Value = this.Width,
                    Width = 100,
                    Anchor = AnchorStyles.Left
                };

                NumericUpDown heightUpDown = new NumericUpDown
                {
                    Minimum = 100,
                    Maximum = 1000,
                    Value = this.Height,
                    Width = 100,
                    Anchor = AnchorStyles.Left
                };

                Button okButton = new Button
                {
                    Text = "确定",
                    DialogResult = DialogResult.OK,
                    Anchor = AnchorStyles.None
                };

                panel.Controls.Add(widthLabel, 0, 0);
                panel.Controls.Add(widthUpDown, 1, 0);
                panel.Controls.Add(heightLabel, 0, 1);
                panel.Controls.Add(heightUpDown, 1, 1);
                panel.Controls.Add(okButton, 1, 2);

                sizeForm.Controls.Add(panel);

                if (sizeForm.ShowDialog(this) == DialogResult.OK)
                {
                    this.Width = (int)widthUpDown.Value;
                    this.Height = (int)heightUpDown.Value;
                }
            }

            // 恢复主窗口的TopMost状态
            this.TopMost = wasTopMost;
        }

        private IntPtr SetKeyboardHook(LowLevelKeyboardProc proc)
        {
            using (var curProcess = System.Diagnostics.Process.GetCurrentProcess())
            using (var curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private IntPtr SetMouseHook(LowLevelMouseProc proc)
        {
            using (var curProcess = System.Diagnostics.Process.GetCurrentProcess())
            using (var curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private IntPtr KeyboardHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                Keys key = (Keys)vkCode;

                if (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN)
                {
                    if (!_pressedKeys.Contains(key))
                    {
                        _pressedKeys.Add(key);
                        UpdateKeyDisplay();
                    }
                }
                else if (wParam == (IntPtr)WM_KEYUP || wParam == (IntPtr)WM_SYSKEYUP)
                {
                    _pressedKeys.Remove(key);
                    UpdateKeyDisplay();
                }
            }
            return CallNextHookEx(_keyboardHookID, nCode, wParam, lParam);
        }

        private IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                if (wParam == (IntPtr)WM_LBUTTONDOWN)
                {
                    _pressedKeys.Add(Keys.LButton);
                    UpdateKeyDisplay();
                }
                else if (wParam == (IntPtr)WM_LBUTTONUP)
                {
                    _pressedKeys.Remove(Keys.LButton);
                    UpdateKeyDisplay();
                }
                else if (wParam == (IntPtr)WM_RBUTTONDOWN)
                {
                    _pressedKeys.Add(Keys.RButton);
                    UpdateKeyDisplay();
                }
                else if (wParam == (IntPtr)WM_RBUTTONUP)
                {
                    _pressedKeys.Remove(Keys.RButton);
                    UpdateKeyDisplay();
                }
                else if (wParam == (IntPtr)WM_MBUTTONDOWN)
                {
                    _pressedKeys.Add(Keys.MButton);
                    UpdateKeyDisplay();
                }
                else if (wParam == (IntPtr)WM_MBUTTONUP)
                {
                    _pressedKeys.Remove(Keys.MButton);
                    UpdateKeyDisplay();
                }
            }
            return CallNextHookEx(_mouseHookID, nCode, wParam, lParam);
        }

        private void UpdateKeyDisplay()
        {
            this.BeginInvoke(new Action(() =>
            {
                if (_pressedKeys.Count > 0)
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (Keys key in _pressedKeys)
                    {
                        if (sb.Length > 0)
                            sb.Append(" + ");
                        sb.Append(GetKeyDisplayName(key));
                    }
                    _lastKeyText = sb.ToString();
                    keyLabel.Text = _lastKeyText;
                }
                // 只有当没有任何按键按下且_lastKeyText为空时才显示"右键自定义"
                else if (string.IsNullOrEmpty(_lastKeyText))
                {
                    keyLabel.Text = "右键自定义";
                }
            }));
        }


        private string GetKeyDisplayName(Keys key)
        {
            switch (key)
            {
                case Keys.LButton:
                    return "左键";
                case Keys.RButton:
                    return "右键";
                case Keys.MButton:
                    return "中键";
                case Keys.LControlKey:
                    return "Ctrl";
                case Keys.RControlKey:
                    return "Ctrl";
                case Keys.LShiftKey:
                    return "Shift";
                case Keys.RShiftKey:
                    return "Shift";
                case Keys.LMenu:
                    return "Alt";
                case Keys.RMenu:
                    return "Alt";
                default:
                    return key.ToString();
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            UnhookWindowsHookEx(_keyboardHookID);
            UnhookWindowsHookEx(_mouseHookID);
            base.OnFormClosing(e);
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
}